/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vng.zing.survey.thrift.client;

import com.vng.jcore.thriftutil.TClientPool;
import com.vng.jcore.thriftutil.TClientPoolConfig;
import com.vng.jcore.thriftutil.TClientPoolMan;
import com.vng.zing.lib.Config;
import com.vng.zing.survey.thrift.model.AnswerItem;
import com.vng.zing.survey.thrift.model.IDSurveyResult;
import com.vng.zing.survey.thrift.model.Response;
import com.vng.zing.survey.thrift.model.SurveyItem;
import com.vng.zing.survey.thrift.model.SurveyItemResult;
import com.vng.zing.survey.thrift.service.SurveyService;
import com.vng.zing.survey.thrift.model.Error;
import com.vng.zing.survey.thrift.model.ShortInfoSurveyItem;
import com.vng.zing.survey.thrift.model.State;
import com.vng.zing.survey.thrift.model.SurveyStatsPerDayItem;
import com.vng.zing.survey.thrift.model.SurveyStatsResult;
import com.vng.zing.survey.thrift.model.UserType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.cliffc.high_scale_lib.NonBlockingHashMap;

/**
 *
 * @author kienpd
 */
public class SurveyClient {

    private static final Lock createLock_ = new ReentrantLock();
    private static final Map<String, SurveyClient> _instances = new NonBlockingHashMap();
    private static final String host = Config.getParamStr("thrift_server", "host");
    private static int port = Config.getParamInt("thrift_server", "port");
    private SurveyService.Client client;
    private TClientPool<SurveyService.Client> Pool;

    public static SurveyClient getInstance() {
        String key = String.format("%s:%s", new Object[]{host, port});

        if (!_instances.containsKey(key)) {
            createLock_.lock();
            try {
                if (_instances.get(key) == null) {
                    _instances.put(key, new SurveyClient());
                }
            } finally {
                createLock_.unlock();
            }
        }
        return _instances.get(key);
    }

    private SurveyClient() {
        TClientPoolConfig.ConnConfig conn_cfg = new TClientPoolConfig.ConnConfig(host, port, true, false, 0);

        // get current pool
        Pool = (TClientPool<SurveyService.Client>) TClientPoolMan.Instance.getPool(host, port, SurveyService.Client.class);
        if (Pool == null) {
            // add client to pool
            TClientPoolMan.Instance.addPool(
                    new TClientPool<SurveyService.Client>(
                            new SurveyService.Client.Factory(), conn_cfg, TClientPoolConfig.DefaultPoolConfig));
            // get current pool
            Pool = (TClientPool<SurveyService.Client>) TClientPoolMan.Instance.getPool(host, port, SurveyService.Client.class);
        }
        assert (Pool != null);

    }

    public int getCountSurvery(int key) throws Exception {

        int count = 0;

        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            count = cli.getCountSurvey(key);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }

        return count;

    }

    public IDSurveyResult newSurvey(int idUser, SurveyItem surveyItem) throws Exception {

        IDSurveyResult iDSurveyResult = new IDSurveyResult();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            iDSurveyResult = cli.newSurvey(idUser, surveyItem);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }

        return iDSurveyResult;

    }

    public SurveyItemResult getSurvey(int idSurvey) throws Exception {

        int count = 0;

        SurveyItemResult itemResult = new SurveyItemResult();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            itemResult = cli.getSurvey(idSurvey);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }

        return itemResult;

    }

    public Error newResponse(int idUser, int idSurvey, Response response) throws Exception {

        Error error;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            error = cli.newResponse(idUser, idSurvey, response);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return error;

    }

    public State checkUser(int idSurvey, int idUser) throws Exception {
        State state;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            state = cli.checkUser(idSurvey, idUser);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return state;

    }

    public SurveyStatsResult getSurveyStats(int idSurvey) throws Exception {
        SurveyStatsResult result;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getSurveyStats(idSurvey);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public Map<Short, Integer> listQuesCanEdit(int idSurvey) throws Exception {
        Map<Short, Integer> result = new HashMap<Short, Integer>();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.listQuesCanEdit(idSurvey);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public List<ShortInfoSurveyItem> getListShortInfoSurveyItem(int idUser, int page, int numOfpage, UserType userType) throws Exception {

        List<ShortInfoSurveyItem> result = new ArrayList<ShortInfoSurveyItem>();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getListShortInfoSurveyItem(idUser, page, numOfpage, userType);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public List<Response> getListResponse(int idSurvey, int page, int numOfpage) throws Exception {

        List<Response> result = new ArrayList<Response>();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getListResponse(idSurvey, page, numOfpage);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public int getCountResByQues(int idSurvey, short idQues) throws Exception {
        int result;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getCountResByQues(idSurvey, idQues);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;
    }

    public List<AnswerItem> getResByQues(int idSurvey, short idQues, int page, int numOfpage) throws Exception {
        List<AnswerItem> result = new ArrayList<AnswerItem>();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getResByQues(idSurvey, idQues, page, numOfpage);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public Error removeSurveyItem(int idSurvey, int idUser) throws Exception, Exception, Exception, Exception, Exception {
        Error result;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.removeSurveyItem(idSurvey, idUser);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public int getCountResponse(int idSurvey) throws Exception {
        int result;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getCountResponse(idSurvey);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public Error removeResponse(int idSurvey, int idUser) throws Exception {
        Error result;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.removeResponse(idSurvey, idUser);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }

    public Error updateSurvey(int idSurvey, SurveyItem surveyItem) throws Exception {

        Error error = Error.IDSURVEY_NO_EXITS;

        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            error = cli.updateSurvey(idSurvey, surveyItem);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }

        return error;

    }

    public List<ShortInfoSurveyItem> getListShortInfoSurveyItemHost(int idUser, int page, int numOfpage) throws Exception {

        List<ShortInfoSurveyItem> result = new ArrayList<ShortInfoSurveyItem>();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getListShortInfoSurveyItemHost(idUser, page, numOfpage);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;
    }

    public int getCountSurveyHost(int idUser) throws Exception {
        int result;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getCountSurveyHost(idUser);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }
    public int getCountSurveyNew(int idUser) throws Exception {
        int result;
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getCountSurveyNew(idUser);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }
    public  List<SurveyStatsPerDayItem> getListStatsSurveyPerDay(int idSurvey) throws Exception{
        
        List<SurveyStatsPerDayItem> result = new ArrayList<SurveyStatsPerDayItem>();
        SurveyService.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.getListStatsSurveyPerDay(idSurvey);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;
    
    
    }
}
